package com.hn.gege.sys.modules.record.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hn.gege.core.common.CommonPage;
import com.hn.gege.core.common.CommonResult;
import com.hn.gege.core.common.BaseController;
import com.hn.gege.core.query.QueryGenerator;
import com.hn.gege.sys.modules.record.entity.Export;
import com.hn.gege.sys.modules.record.service.IExportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


@Api(tags = "record-ExportController", description = "导出记录管理")
@RestController
@RequestMapping("/record/export")
@Validated
public class ExportController extends BaseController {

    @Autowired
    IExportService exportService;

    @ApiOperation("导出记录分页列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "pageNo", value = "当前页", required = true, dataType = "Integer", paramType = "query"),
        @ApiImplicitParam(name = "pageSize", value = "每页数量", required = true, dataType = "Integer", paramType = "query"),
    })
    @GetMapping("/pageInfo")
    public CommonPage<Export> pageInfo(@NotNull Integer pageNo,
                                   @NotNull Integer pageSize,
                                   Export export,
                                   HttpServletRequest request){
        Page<Export> pageInfo = new Page<>(pageNo, pageSize);
        QueryWrapper<Export> qw = QueryGenerator.initQueryWrapper(export, request.getParameterMap());
        Page<Export> page1 = exportService.page(pageInfo, qw);
        return CommonPage.restPage(page1);
    }

    @ApiOperation("通过主键获取导出记录")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "记录ID", required = true, dataType = "String", paramType = "path")
    })
    @GetMapping("/{id}")
    public CommonResult<Export> getByPk(@NotBlank@PathVariable("id") String id){
        Export export = exportService.getByPk(id);
        return CommonResult.success(export);
    }

    @ApiOperation("新增导出记录")
    @PostMapping
    public CommonResult add(@Validated Export export, BindingResult bindingResult){
        boolean b = exportService.save(export);
        if (b){
            return CommonResult.success("成功");
        }
        return CommonResult.failed("失败");
    }

    @ApiOperation("修改导出记录")
    @PutMapping
    public CommonResult updateByPk(@Validated Export export, BindingResult bindingResult){
        boolean b = exportService.updateByPk(export);
        if (b){
            return CommonResult.success("成功");
        }
        return CommonResult.failed("失败");
    }

    @ApiOperation("通过主键删除导出记录")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "记录ID", required = true, dataType = "String", paramType = "path")
    })
    @DeleteMapping("/{id}")
    public CommonResult removeByPk(@NotBlank@PathVariable("id") String id){
        boolean b = exportService.removeByPk(id);
        if (b){
            return CommonResult.success("成功");
        }
        return CommonResult.failed("失败");
    }


    @Autowired
    private WebApplicationContext applicationContext;

    @ApiOperation("获取项目所有接口地址列表")
    @GetMapping(value = "getAllUrl")
    public CommonResult<Object> getAllUrl() throws ClassNotFoundException {

        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> mappingHandlerMethods = mapping.getHandlerMethods();
        ArrayList<HashMap<String, Object>> list = new ArrayList<>();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> map : mappingHandlerMethods.entrySet()) {
            HashMap<String, Object> pmap = new HashMap<>();
            RequestMappingInfo info = map.getKey();
            HandlerMethod method = map.getValue();
            PatternsRequestCondition patternsCondition = info.getPatternsCondition();
            String className = method.getMethod().getDeclaringClass().getName();
            /**
             * 匹配包路径 根据自己的路径替换
             */
            if (className.contains("com.hn.gege")) {
                //获取类对象
                Class clazz = Class.forName(method.getMethod().getDeclaringClass().getName());
                String metName = method.getMethod().getName();
                /**
                 * 因为单独获取一个类对象要指定参数，不适合批量使用，所以获取所有的方法然后根据name筛选
                 */
                Method[] clazzDeclaredMethods = clazz.getDeclaredMethods();
                Arrays.stream(clazzDeclaredMethods).forEach(
                        c -> {
                            if(c.getName().equals(metName)){
                                /* swagger注解 可以换成别的 */
                                ApiOperation annotation = c.getAnnotation(ApiOperation.class);
                                if(null != annotation){
                                    pmap.put("Desc",annotation.value());
                                }
                            }
                        }
                );
                for(String url : patternsCondition.getPatterns()) {
                    pmap.put("url", url);
                }
                list.add(pmap);
            }
        }
        return CommonResult.success(list);
    }

    @Autowired
    DocumentationCache documentationCache;
    @ApiOperation("获取所有接口")
    @GetMapping("/test")
    public CommonResult test(){
        Map<String, Documentation> all = documentationCache.all();
        return CommonResult.success(all);
    }


}
